﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using NetCoreCMS.Common;
using NetCoreCMS.IServices;
using NetCoreCMS.Models;
using NetCoreCMS.PayAPI.wxpay;
using ThoughtWorks.QRCode.Codec;

namespace NetCoreCMS.Web.Areas.Payments.Controllers
{    
    public class WxNatPayController : AreasController
    {
        public IUser_rechargeService _user_recharge { get; set; }
        public IOrdersService _orders { get; set; }
        public ISite_paymentService _site_payment { get; set; }
        public IPaymentService _payment { get; set; }
        public IUser_point_logService _user_point_log { get; set; }
        protected string order_no = string.Empty;
        public IActionResult Index()
        {
            int site_payment_id = 0; //订单支付方式

            //=============================获得订单信息================================
            order_no = CMSRequest.GetFormString("pay_order_no", HttpContext).ToUpper();
            decimal order_amount = CMSRequest.GetFormDecimal("pay_order_amount", 0, HttpContext);
            string user_name = CMSRequest.GetFormString("pay_user_name", HttpContext);
            string subject = CMSRequest.GetFormString("pay_subject", HttpContext);
            //检查参数是否正确
            if (string.IsNullOrEmpty(order_no) || order_amount == 0)
            {
                return ToError("对不起，您提交的参数有误！");
            }
            //===============================判断订单==================================
            if (order_no.StartsWith("R")) //R开头为在线充值订单
            {
                User_recharge model = _user_recharge.GetModel(order_no);
                if (model == null)
                {
                    return ToError("对不起，您充值的订单号不存在或已删除！");
                }
                if (model.amount != order_amount)
                {
                    return ToError("对不起，您充值的订单金额与实际金额不一致！");
                }
                if (model.status == 1)
                {
                    return Redirect("/Web/Payment/Index?action=succeed&order_no=" + order_no);
                }
                site_payment_id = model.payment_id; //站点支付方式ID
            }
            else //B开头为商品订单
            {
                Orders model = _orders.GetModel(order_no);
                if (model == null)
                {
                    return ToError("对不起，您支付的订单号不存在或已删除！");  
                }
                if (model.order_amount != order_amount)
                {
                    return ToError("对不起，您支付的订单金额与实际金额不一致！");        
                }
                if (model.payment_status == 2)
                {
                    return Redirect("/Web/Payment/Index?action=succeed&order_no=" + order_no);
                }
                site_payment_id = model.payment_id; //站点支付方式ID
            }
            if (user_name != "")
            {
                user_name = "支付会员：" + user_name;
            }
            else
            {
                user_name = "匿名用户";
            }
            var site_paymentModel = _site_payment.GetModel(site_payment_id);
            var paymentModel = _payment.GetModel(site_payment_id);
            //===========================调用统一下单接口==============================
            string sendUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
            NativeConfig nativeConfig = new NativeConfig(site_paymentModel, paymentModel, sysConfig, HttpContext);
            WxPayData data = new WxPayData();
            data.SetValue("body", user_name); //商品描述
            data.SetValue("detail", sysConfig.webname + "-" + subject); //商品详情
            data.SetValue("out_trade_no", order_no); //商户订单号
            data.SetValue("total_fee", (Convert.ToDouble(order_amount) * 100).ToString()); //订单总金额,以分为单位
            data.SetValue("trade_type", "NATIVE");//交易类型
            data.SetValue("product_id", order_no);//商品ID
            data.SetValue("notify_url", nativeConfig.Notify_url); //异步通知url
            data.SetValue("spbill_create_ip", CMSRequest.GetClientUserIp(HttpContext)); //终端IP
            data.SetValue("appid", nativeConfig.AppId); //公众账号ID
            data.SetValue("mch_id", nativeConfig.Partner); //商户号
            data.SetValue("nonce_str", NativePay.GenerateNonceStr()); //随机字符串
            data.SetValue("sign", data.MakeSign(nativeConfig.Key)); //签名
            string xml = data.ToXml(); //转换成XML
            var startTime = DateTime.Now; //开始时间
            string response = HttpService.Post(xml, sendUrl, false, 6); //发送请求
            var endTime = DateTime.Now; //结束时间
            int timeCost = (int)((endTime - startTime).TotalMilliseconds); //计算所用时间
            WxPayData result = new WxPayData();
            result.FromXml(response, nativeConfig.Key);
            NativePay.ReportCostTime(site_paymentModel, paymentModel, sysConfig, HttpContext, sendUrl, timeCost, result); //测速上报

            string codeUrl = result.GetValue("code_url").ToString();//获得统一下单接口返回的二维码链接
            ViewBag.imgQRCode = "qrcode?data=" + Utils.UrlEncode(codeUrl);
            ViewBag.litText = order_amount.ToString("#0.00");
            ViewBag.order_no = order_no;
            return View();
        }
        public IActionResult qrcode()
        {
            if (!string.IsNullOrEmpty(CMSRequest.GetString("data", HttpContext)))
            {
                string str = CMSRequest.GetString("data", HttpContext);

                //初始化二维码生成工具
                QRCodeEncoder qrCodeEncoder = new QRCodeEncoder();
                qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE;
                qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M;
                qrCodeEncoder.QRCodeVersion = 0;
                qrCodeEncoder.QRCodeScale = 4;

                //将字符串生成二维码图片
                Bitmap image = qrCodeEncoder.Encode(str, Encoding.Default);

                //保存为PNG到内存流  
                MemoryStream ms = new MemoryStream();
                image.Save(ms, ImageFormat.Png);
                //输出二维码图片
                return new FileStreamResult(ms, "image/png");
            }
            return null;
        }
        public IActionResult return_url()
        {
            string order_no = CMSRequest.GetString("order_no", HttpContext).ToUpper();
            if (order_no.StartsWith("R")) //充值订单
            {
                User_recharge model = _user_recharge.GetModel(order_no);
                if (model != null && model.status == 1)
                {
                    string resurl = "/Web/Payment/Index?action=succeed&order_no=" + order_no;
                    return Content("{\"status\": 1, \"url\": \"" + resurl + "\"}");
                }
            }
            else if (order_no.StartsWith("B")) //商品订单
            {
                Orders model = _orders.GetModel(order_no);
                if (model != null && model.payment_status == 2)
                {
                    string resurl = "/Web/Payment/Index?action=succeed&order_no=" + order_no;
                    return Content("{\"status\": 1, \"url\": \"" + resurl + "\"}");
                }
            }
            return Content("{\"status\": 0, \"msg\": \"订单未支付成功！\"}");
        }
        public async Task<IActionResult> notify_url()
        {
            int site_payment_id = 0;
            WxPayData requestData = new WxPayData();
            await requestData.GetRequest(HttpContext); //获取微信传过来的参数
            if (!requestData.IsSet("transaction_id"))
            {
                //若transaction_id不存在，则立即返回结果给微信支付后台
                WxPayData res = new WxPayData();
                res.SetValue("return_code", "FAIL");
                res.SetValue("return_msg", "支付结果中微信订单号不存在");
                return Content(res.ToXml());
            }
            //获取订单信息
            string transaction_id = requestData.GetValue("transaction_id").ToString(); //微信支付订单号
            string order_no = requestData.GetValue("out_trade_no").ToString().ToLower(); //商户订单号
            string total_fee = requestData.GetValue("total_fee").ToString(); //获取总金额
            if (order_no.StartsWith("R")) //充值订单
            {
                site_payment_id = _user_recharge.GetModel(order_no).payment_id;
            }
            else if (order_no.StartsWith("B")) //商品订单
            {
                site_payment_id = _orders.GetModel(order_no).payment_id;
            }
            if (site_payment_id == 0)
            {
                //若订单查询失败，则立即返回结果给微信支付后台
                WxPayData res = new WxPayData();
                res.SetValue("return_code", "FAIL");
                res.SetValue("return_msg", "订单不存在或已删除");
                return Content(res.ToXml());
            }
            var site_paymentModel = _site_payment.GetList().FirstOrDefault(a => a.payment_id == site_payment_id);
            var paymentModel = _payment.GetModel(site_payment_id);
            //开始验证订单
            WxPayData notifyData = await NativePay.GetNotifyData(site_paymentModel, paymentModel, sysConfig, HttpContext);
            //查询订单，判断订单真实性
            if (!QueryOrder(transaction_id, site_paymentModel,paymentModel))
            {
                //若订单查询失败，则立即返回结果给微信支付后台
                WxPayData res = new WxPayData();
                res.SetValue("return_code", "FAIL");
                res.SetValue("return_msg", "订单查询失败");
                return Content(res.ToXml());
            }

            if (order_no.StartsWith("R")) //充值订单
            {
                User_recharge model = _user_recharge.GetModel(order_no);
                if (model == null)
                {
                    WxPayData res = new WxPayData();
                    res.SetValue("return_code", "FAIL");
                    res.SetValue("return_msg", "该订单号不存在");
                    return Content(res.ToXml());
                }
                if (model.status == 1) //已成功
                {
                    WxPayData res = new WxPayData();
                    res.SetValue("return_code", "SUCCESS");
                    res.SetValue("return_msg", "OK");
                    return Content(res.ToXml());
                }
                if (model.amount != (decimal.Parse(total_fee) / 100))
                {
                    WxPayData res = new WxPayData();
                    res.SetValue("return_code", "FAIL");
                    res.SetValue("return_msg", "订单金额和支付金额不相符");
                    return Content(res.ToXml());
                }
                bool result = _user_recharge.Confirm(order_no);
                if (!result)
                {
                    WxPayData res = new WxPayData();
                    res.SetValue("return_code", "FAIL");
                    res.SetValue("return_msg", "修改订单状态失败");
                    return Content(res.ToXml());
                }
            }
            else if (order_no.StartsWith("B")) //商品订单
            {
                Orders model = _orders.GetModel(order_no);
                if (model == null)
                {
                    WxPayData res = new WxPayData();
                    res.SetValue("return_code", "FAIL");
                    res.SetValue("return_msg", "该订单号不存在");
                    return Content(res.ToXml());
                }
                if (model.payment_status == 2) //已付款
                {
                    WxPayData res = new WxPayData();
                    res.SetValue("return_code", "SUCCESS");
                    res.SetValue("return_msg", "OK");
                    return Content(res.ToXml());
                }
                if (model.order_amount != (decimal.Parse(total_fee) / 100))
                {
                    WxPayData res = new WxPayData();
                    res.SetValue("return_code", "FAIL");
                    res.SetValue("return_msg", "订单金额和支付金额不相符");
                    return Content(res.ToXml());
                }
                bool result = _orders.UpdateField(order_no, "trade_no='" + transaction_id + "',status=2,payment_status=2,payment_time='" + DateTime.Now + "'");
                if (!result)
                {
                    WxPayData res = new WxPayData();
                    res.SetValue("return_code", "FAIL");
                    res.SetValue("return_msg", "修改订单状态失败");
                    return Content(res.ToXml());
                }
                //扣除积分
                if (model.point < 0)
                {
                    _user_point_log.Add(model.user_id, model.user_name, model.point, "换购扣除积分，订单号：" + model.order_no, false);
                }
            }

            //返回成功通知
            WxPayData res1 = new WxPayData();
            res1.SetValue("return_code", "SUCCESS");
            res1.SetValue("return_msg", "OK");
            return Content(res1.ToXml());
        }
        //查询订单
        private bool QueryOrder(string transaction_id, Site_payment model, Payment payModel)
        {
            WxPayData req = new WxPayData();
            req.SetValue("transaction_id", transaction_id);
            WxPayData res = NativePay.OrderQuery(model,payModel,sysConfig,HttpContext, req);
            if (res.GetValue("return_code").ToString() == "SUCCESS" &&
                res.GetValue("result_code").ToString() == "SUCCESS")
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}